#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
工具函数集合
包含地址解析、文件处理等通用工具函数
"""

import re
import os
import platform
import subprocess
from app.config import GUANGDONG_DISTRICTS, SPECIAL_AREAS, GUANGDONG_POSTAL_CODES


def parse_address(address):
    """解析地址，提取省、市、区（镇）、邮政编码信息
    
    Args:
        address: 地址字符串
        
    Returns:
        tuple: (省, 市, 区(镇), 邮政编码)
    """
    province = ""
    city = ""
    district = ""
    postal_code = ""
    district_found = False
    
    try:
        # 首先提取省份
        province_pattern = r'([\u4e00-\u9fa5]+省)'
        province_matches = re.findall(province_pattern, address)
        if province_matches:
            province = province_matches[0]
        
        # 提取市（排除省名）
        # 先去掉省名，再提取市名
        address_without_province = address
        if province:
            address_without_province = address.replace(province, '')
        
        # 改进市名提取逻辑，避免匹配到"口岸市场"等词汇中的"市"
        # 优先匹配已知的广东省城市
        for known_city in GUANGDONG_DISTRICTS.keys():
            if known_city in address_without_province:
                city = known_city
                break
        
        # 如果没有匹配到已知城市，使用更精确的正则
        if not city:
            # 匹配位置更靠前的市名（通常真正的市名在地址开头部分）
            city_pattern = r'^([^省]*?)([\u4e00-\u9fa5]{2,5}市)'
            city_match = re.search(city_pattern, address_without_province)
            if city_match:
                city = city_match.group(2)
        
        # 如果没有从地址中提取到省份，根据城市推断省份（这里以广东省为主）
        if not province and city in GUANGDONG_DISTRICTS:
            province = '广东省'
        
        # 如果市名不在GUANGDONG_DISTRICTS中，可能是县级市，需要进一步检查
        if not province and city:
            for potential_parent_city, districts in GUANGDONG_DISTRICTS.items():
                if city in districts:
                    # 找到了，这是一个县级市
                    province = '广东省'
                    # 将县级市信息调整：原来的city变成district，parent_city变成city
                    district = city
                    city = potential_parent_city
                    district_found = True
                    break
        
        # 如果没有提取到市，尝试从县级地址中推断市和省
        if not city:
            # 检查是否是县级地址（县/县级市直接开头）
            for potential_city, districts in GUANGDONG_DISTRICTS.items():
                for district_name in districts:
                    if address.startswith(district_name):
                        # 找到匹配的县/县级市
                        city = potential_city
                        province = '广东省'
                        
                        # 对于县级地址，使用县/区级别作为区域
                        # 不提取更下级的镇，保持在县/区这个级别
                        district = district_name
                        
                        district_found = True
                        break
                if city:  # 找到就跳出外层循环
                    break
        
        # 如果仍然没有找到市，尝试通过区县镇名反向查找所属市
        if not city:
            # 从地址中提取可能的区县镇名，然后在GUANGDONG_DISTRICTS中查找
            for potential_city, districts in GUANGDONG_DISTRICTS.items():
                for district_name in districts:
                    if district_name in address:
                        # 找到匹配的区县镇
                        city = potential_city
                        province = '广东省'
                        district = district_name
                        district_found = True
                        break
                if city:  # 找到就跳出外层循环
                    break
        
        # 提取区/镇/县
        # 首先尝试匹配标准行政区划（如果之前没有在县级地址处理中找到）
        if not district_found and city in GUANGDONG_DISTRICTS:
            for std_district in GUANGDONG_DISTRICTS[city]:
                if std_district in address:
                    district = std_district
                    district_found = True
                    break
        
        # 如果没有找到标准区划，尝试匹配功能区等
        if not district_found:
            # 创建一个清理后的地址，去掉省市信息，便于精确提取区域
            clean_address = address
            if province:
                clean_address = clean_address.replace(province, '')
            if city:
                clean_address = clean_address.replace(city, '')
            
            # 使用更精确的正则表达式提取区域名称
            # 按照优先级排序：先匹配特殊区域，再匹配一般区域
            area_patterns = [
                # 先匹配特定的命名新区（避免被通用"新区"匹配）
                r'([\u4e00-\u9fa5]{2,4}新区)',  # 匹配如"翠亨新区"、"前海新区"等
                r'(高新技术产业开发区)',  # 完整匹配，不使用字符类和+
                r'(经济技术开发区)', 
                r'([\u4e00-\u9fa5]{2,4}开发区)',  # 匹配如"火炬开发区"等
                r'(保税区)',  # 完整匹配
                r'(高新区)',  # 完整匹配
                r'(新区)',  # 通用新区匹配（优先级降低）
                # 匹配完整的区域名称（优先匹配较长的）
                r'([\u4e00-\u9fa5]{3,4}区)',   # 匹配3-4字符的区名（如"香洲区"、"南山区"）
                r'([\u4e00-\u9fa5]{2}区)',     # 匹配2字符的区名
                r'([\u4e00-\u9fa5]{2,4}县)',   # 匹配2-4字符的县名
                r'([\u4e00-\u9fa5]{2,4}镇)',   # 匹配2-4字符的镇名
                # 最后匹配单字符区域（避免误匹配）
                r'([东西南北中]区)',          # 匹配方位区名
                # 单字符区域匹配（非常保守，只匹配确定的方位区名）
                r'([\u4e00-\u9fa5]县)',       # 匹配单字符县名
                r'([\u4e00-\u9fa5]镇)'        # 匹配单字符镇名
                # 注意：移除了过于宽泛的单字符区名匹配，避免误匹配
            ]
            
            for pattern in area_patterns:
                # 在清理后的地址中查找
                matches = re.findall(pattern, clean_address)
                if matches:
                    potential_district = matches[0]
                    
                    # 额外验证：检查提取的区域是否合理
                    # 如果是单字符区域，需要更严格的验证
                    if len(potential_district) == 2 and potential_district.endswith(('区', '县', '镇')):
                        # 检查这个区域前后的字符，确保它确实是一个独立的行政区域
                        district_pattern = re.escape(potential_district)
                        # 检查区域前面是否是市名或者在地址开头
                        if city:
                            city_district_pattern = re.escape(city) + r'[\s]*' + district_pattern
                            if not re.search(city_district_pattern, address):
                                # 如果不是紧跟在市名后面，可能是误匹配，跳过
                                continue
                    
                    # 检查是否为特殊区域需要映射
                    if potential_district in SPECIAL_AREAS and SPECIAL_AREAS[potential_district]:
                        district = SPECIAL_AREAS[potential_district]
                    else:
                        # 直接使用提取的区域名称
                        district = potential_district
                    
                    # print(f"通过正则匹配到区域: {district} (来源: {potential_district}, 模式: {pattern}, 清理后地址: {clean_address})")
                    
                    # 找到就跳出循环
                    if district:
                        break
        
        # 根据城市获取邮政编码
        if city in GUANGDONG_POSTAL_CODES:
            postal_code = GUANGDONG_POSTAL_CODES[city]
        
    except Exception as e:
        print(f"地址解析出错: {e}")
    
    return province, city, district, postal_code


def open_file_explorer(path):
    """跨平台打开文件资源管理器
    
    Args:
        path: 要打开的目录路径
        
    Returns:
        bool: 是否成功打开
    """
    try:
        if not os.path.exists(path):
            return False
            
        if platform.system() == "Windows":
            os.startfile(path)
        elif platform.system() == "Darwin":  # macOS
            subprocess.run(["open", path])
        else:  # Linux
            subprocess.run(["xdg-open", path])
        return True
    except Exception as e:
        print(f"打开文件夹失败: {e}")
        return False


def ensure_directory(path):
    """确保目录存在，如果不存在则创建
    
    Args:
        path: 目录路径
        
    Returns:
        bool: 是否成功创建或已存在
    """
    try:
        os.makedirs(path, exist_ok=True)
        return True
    except Exception as e:
        print(f"创建目录失败: {e}")
        return False


def validate_file_extension(file_path, allowed_extensions):
    """验证文件扩展名
    
    Args:
        file_path: 文件路径
        allowed_extensions: 允许的扩展名列表
        
    Returns:
        bool: 文件扩展名是否有效
    """
    if not file_path:
        return False
    
    file_ext = os.path.splitext(file_path.lower())[1]
    return file_ext in [ext.lower() for ext in allowed_extensions]


def format_time_range(time_range):
    """格式化时间范围字符串用于文件名
    
    Args:
        time_range: 时间范围字符串，如 "2025Q1-2025Q2"
        
    Returns:
        str: 格式化后的字符串，如 "2025Q1_2025Q2"
    """
    return time_range.replace('-', '_')


def parse_quarters(time_range):
    """解析时间范围字符串为季度列表
    
    Args:
        time_range: 时间范围字符串，如 "2025Q1-2025Q2" 或 "2025Q1"
        
    Returns:
        list: 季度列表，如 ["2025Q1", "2025Q2"]
    """
    if '-' not in time_range:
        return [time_range.strip()]
    
    start, end = time_range.split('-')
    start = start.strip()
    end = end.strip()
    
    # 解析季度
    start_match = re.match(r'(\d{4})Q(\d)', start)
    end_match = re.match(r'(\d{4})Q(\d)', end)
    
    if not start_match or not end_match:
        raise ValueError(f"时间范围格式错误: {time_range}")
    
    start_year, start_quarter = int(start_match.group(1)), int(start_match.group(2))
    end_year, end_quarter = int(end_match.group(1)), int(end_match.group(2))
    
    quarters = []
    current_year, current_quarter = start_year, start_quarter
    
    while current_year < end_year or (current_year == end_year and current_quarter <= end_quarter):
        quarters.append(f"{current_year}Q{current_quarter}")
        current_quarter += 1
        if current_quarter > 4:
            current_quarter = 1
            current_year += 1
    
    return quarters


def is_valid_quarter_format(quarter_str):
    """验证季度格式是否正确
    
    Args:
        quarter_str: 季度字符串，如 "2025Q1"
        
    Returns:
        bool: 格式是否正确
    """
    pattern = r'^\d{4}Q[1-4]$'
    return bool(re.match(pattern, quarter_str.strip()))


def get_file_size_mb(file_path):
    """获取文件大小（MB）
    
    Args:
        file_path: 文件路径
        
    Returns:
        float: 文件大小（MB），文件不存在返回0
    """
    try:
        if os.path.exists(file_path):
            size_bytes = os.path.getsize(file_path)
            return round(size_bytes / (1024 * 1024), 2)
        return 0
    except:
        return 0


def format_date_for_display(date_str):
    """格式化日期显示为 2025/4/21 格式
    
    Args:
        date_str: 原始日期字符串，如 "2025年04月16日"
        
    Returns:
        str: 格式化后的日期，如 "2025/4/16"
    """
    if not date_str:
        return ""
    
    try:
        # 使用正则表达式提取年月日
        date_pattern = r'(\d{4})\s*年\s*(\d{1,2})\s*月\s*(\d{1,2})\s*日'
        match = re.search(date_pattern, date_str)
        
        if match:
            year = match.group(1)
            month = str(int(match.group(2)))  # 去掉前导0
            day = str(int(match.group(3)))    # 去掉前导0
            return f"{year}/{month}/{day}"
        
        # 如果没有匹配到，返回原字符串
        return date_str
    except Exception as e:
        print(f"日期格式化出错: {e}")
        return date_str
